package com.ruoyi.rabbitmq.service;

import com.ruoyi.rabbitmq.config.RabbitMQConfig;
import com.ruoyi.rabbitmq.domain.MessageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 业务消息服务
 * 展示如何在实际业务中使用RabbitMQ
 * 
 * @author ruoyi
 */
@Service
@ConditionalOnProperty(name = "spring.rabbitmq.enabled", havingValue = "true", matchIfMissing = true)
public class BusinessMessageService
{
    private static final Logger log = LoggerFactory.getLogger(BusinessMessageService.class);

    @Autowired
    private MessagePublisher messagePublisher;

    /**
     * 发送用户注册消息
     * 
     * @param userId 用户ID
     * @param username 用户名
     * @param email 邮箱
     */
    public void sendUserRegistrationMessage(Long userId, String username, String email)
    {
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("userId", userId);
        userInfo.put("username", username);
        userInfo.put("email", email);
        userInfo.put("action", "USER_REGISTRATION");
        userInfo.put("timestamp", System.currentTimeMillis());

        try
        {
            // 发送到直连队列，用于用户注册后的业务处理
            String messageId = messagePublisher.sendDirectMessage(userInfo);
            log.info("用户注册消息发送成功，用户ID: {}, 消息ID: {}", userId, messageId);

            // 发送到主题队列，用于通知相关服务
            String topicMessageId = messagePublisher.sendTopicMessage(userInfo, "user.registration");
            log.info("用户注册主题消息发送成功，用户ID: {}, 消息ID: {}", userId, topicMessageId);

            // 发送到扇形队列，用于广播通知
            String fanoutMessageId = messagePublisher.sendFanoutMessage(userInfo);
            log.info("用户注册广播消息发送成功，用户ID: {}, 消息ID: {}", userId, fanoutMessageId);
        }
        catch (Exception e)
        {
            log.error("发送用户注册消息失败，用户ID: {}", userId, e);
            throw new RuntimeException("发送用户注册消息失败", e);
        }
    }

    /**
     * 发送订单创建消息
     * 
     * @param orderId 订单ID
     * @param userId 用户ID
     * @param amount 订单金额
     */
    public void sendOrderCreatedMessage(Long orderId, Long userId, Double amount)
    {
        Map<String, Object> orderInfo = new HashMap<>();
        orderInfo.put("orderId", orderId);
        orderInfo.put("userId", userId);
        orderInfo.put("amount", amount);
        orderInfo.put("action", "ORDER_CREATED");
        orderInfo.put("timestamp", System.currentTimeMillis());

        try
        {
            // 发送到直连队列，用于订单处理
            String messageId = messagePublisher.sendDirectMessage(orderInfo);
            log.info("订单创建消息发送成功，订单ID: {}, 消息ID: {}", orderId, messageId);

            // 发送延迟消息，用于订单超时处理
            String delayMessageId = messagePublisher.sendRetryMessage(orderInfo, 30 * 60 * 1000); // 30分钟
            log.info("订单超时检查消息发送成功，订单ID: {}, 消息ID: {}", orderId, delayMessageId);
        }
        catch (Exception e)
        {
            log.error("发送订单创建消息失败，订单ID: {}", orderId, e);
            throw new RuntimeException("发送订单创建消息失败", e);
        }
    }

    /**
     * 发送邮件通知消息
     * 
     * @param to 收件人
     * @param subject 主题
     * @param content 内容
     */
    public void sendEmailNotificationMessage(String to, String subject, String content)
    {
        Map<String, Object> emailInfo = new HashMap<>();
        emailInfo.put("to", to);
        emailInfo.put("subject", subject);
        emailInfo.put("content", content);
        emailInfo.put("action", "EMAIL_NOTIFICATION");
        emailInfo.put("timestamp", System.currentTimeMillis());

        try
        {
            // 发送到主题队列，用于邮件服务处理
            String messageId = messagePublisher.sendTopicMessage(emailInfo, "email.notification");
            log.info("邮件通知消息发送成功，收件人: {}, 消息ID: {}", to, messageId);
        }
        catch (Exception e)
        {
            log.error("发送邮件通知消息失败，收件人: {}", to, e);
            throw new RuntimeException("发送邮件通知消息失败", e);
        }
    }

    /**
     * 发送系统通知消息
     * 
     * @param title 标题
     * @param content 内容
     * @param targetUsers 目标用户列表
     */
    public void sendSystemNotificationMessage(String title, String content, String[] targetUsers)
    {
        Map<String, Object> notificationInfo = new HashMap<>();
        notificationInfo.put("title", title);
        notificationInfo.put("content", content);
        notificationInfo.put("targetUsers", targetUsers);
        notificationInfo.put("action", "SYSTEM_NOTIFICATION");
        notificationInfo.put("timestamp", System.currentTimeMillis());

        try
        {
            // 发送到扇形队列，用于广播系统通知
            String messageId = messagePublisher.sendFanoutMessage(notificationInfo);
            log.info("系统通知消息发送成功，标题: {}, 消息ID: {}", title, messageId);
        }
        catch (Exception e)
        {
            log.error("发送系统通知消息失败，标题: {}", title, e);
            throw new RuntimeException("发送系统通知消息失败", e);
        }
    }

    /**
     * 发送定时任务消息
     * 
     * @param taskName 任务名称
     * @param taskData 任务数据
     * @param delayMillis 延迟时间
     */
    public void sendScheduledTaskMessage(String taskName, Object taskData, long delayMillis)
    {
        Map<String, Object> taskInfo = new HashMap<>();
        taskInfo.put("taskName", taskName);
        taskInfo.put("taskData", taskData);
        taskInfo.put("action", "SCHEDULED_TASK");
        taskInfo.put("timestamp", System.currentTimeMillis());

        try
        {
            // 发送延迟消息，用于定时任务执行
            String messageId = messagePublisher.sendRetryMessage(taskInfo, delayMillis);
            log.info("定时任务消息发送成功，任务名称: {}, 延迟时间: {}ms, 消息ID: {}", taskName, delayMillis, messageId);
        }
        catch (Exception e)
        {
            log.error("发送定时任务消息失败，任务名称: {}", taskName, e);
            throw new RuntimeException("发送定时任务消息失败", e);
        }
    }

    /**
     * 发送带过期时间的消息
     * 
     * @param content 消息内容
     * @param expiration 过期时间（毫秒）
     */
    public void sendMessageWithExpiration(Object content, long expiration)
    {
        try
        {
            String messageId = messagePublisher.sendMessageWithExpiration(
                content, 
                RabbitMQConfig.DIRECT_EXCHANGE, 
                RabbitMQConfig.DIRECT_ROUTING_KEY, 
                "EXPIRATION", 
                expiration
            );
            log.info("带过期时间的消息发送成功，过期时间: {}ms, 消息ID: {}", expiration, messageId);
        }
        catch (Exception e)
        {
            log.error("发送带过期时间的消息失败", e);
            throw new RuntimeException("发送带过期时间的消息失败", e);
        }
    }

    /**
     * 发送死信消息（用于测试死信队列）
     * 
     * @param content 消息内容
     */
    public void sendDeadLetterMessage(Object content)
    {
        try
        {
            String messageId = messagePublisher.sendDeadLetterMessage(content);
            log.info("死信消息发送成功，消息ID: {}", messageId);
        }
        catch (Exception e)
        {
            log.error("发送死信消息失败", e);
            throw new RuntimeException("发送死信消息失败", e);
        }
    }
} 